/*
 * Copyright 2010 Chad Retz
 * 
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * 
 * http://www.apache.org/licenses/LICENSE-2.0
 * 
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */
package org.jdocng.shared.context;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.jdocng.shared.Configuration;
import org.jdocng.shared.model.ClassDocImpl;
import org.jdocng.shared.model.Logger;
import org.jdocng.shared.model.PackageDocImpl;
import org.jdocng.shared.model.RootDocImpl;

import com.google.common.annotations.GwtCompatible;
import com.sun.javadoc.Type;

/**
 * Standard context storing things in large, simple collections.
 * <p>
 * Not yet implemented
 *
 * @author Chad Retz
 */
@GwtCompatible
public class StandardContext implements Context {

    private Configuration configuration;
    private Logger logger;
    private Messages messages;
    private final Map<String, ClassDocImpl> classes =
        new HashMap<String, ClassDocImpl>();
    private final Map<String, PackageDocImpl> packages =
        new HashMap<String, PackageDocImpl>();
    private final Map<String, Type> types =
        new HashMap<String, Type>();
    private RootDocImpl rootDoc;
    
    @Override
    public Configuration getConfiguration() {
        return configuration;
    }

    @Override
    public void setConfiguration(Configuration configuration) {
        this.configuration = configuration;
    }

    @Override
    public Logger getLogger() {
        return logger;
    }

    @Override
    public void setLogger(Logger logger) {
        this.logger = logger;
    }
    
    @Override
    public Messages getMessages() {
        return messages;
    }
    
    @Override
    public void setMessages(Messages messages) {
        this.messages = messages;
    }
    
    @Override
    public RootDocImpl getRootDoc() {
        if (rootDoc == null) {
            String[] classArray = new String[classes.size()];
            int index = -1;
            for (ClassDocImpl clazz : classes.values()) {
                classArray[++index] = clazz.name();
            }
            String[] packageArray = new String[packages.size()];
            index = -1;
            for (PackageDocImpl pkg : packages.values()) {
                packageArray[++index] = pkg.name();
            }
            rootDoc = new RootDocImpl();
            rootDoc.setContext(this);
            //TODO: figure out specified
            rootDoc.setClasses(classArray);
            rootDoc.setSpecifiedClasses(classArray);
            rootDoc.setSpecifiedPackages(packageArray);
        }
        return rootDoc;
    }

    @Override
    public ClassDocImpl[] getAllClassDocs() {
        return classes.values().toArray(new ClassDocImpl[0]);
    }

    @Override
    public ClassDocImpl getClassDoc(String className) {
        return classes.get(className);
    }

    @Override
    public ClassDocImpl[] getClassDocs(String... classNames) {
        List<ClassDocImpl> ret = new ArrayList<ClassDocImpl>(classNames.length);
        for (String className : classNames) {
            ret.add(classes.get(className));
        }
        return ret.toArray(new ClassDocImpl[0]);
    }
    
    public Map<String, ClassDocImpl> getClasses() {
        return classes;
    }

    @Override
    public PackageDocImpl[] getAllPackageDocs() {
        return packages.values().toArray(new PackageDocImpl[0]);
    }

    @Override
    public PackageDocImpl getPackageDoc(String packageName) {
        return packages.get(packageName);
    }

    @Override
    public PackageDocImpl[] getPackageDocs(String... packageNames) {
        List<PackageDocImpl> ret = new ArrayList<PackageDocImpl>(packageNames.length);
        for (String packageName : packageNames) {
            ret.add(packages.get(packageName));
        }
        return ret.toArray(new PackageDocImpl[0]);
    }
    
    public Map<String, PackageDocImpl> getPackages() {
        return packages;
    }

    @Override
    public Type[] getAllTypes() {
        return types.values().toArray(new Type[0]);
    }

    @Override
    public Type getType(String typeName) {
        return types.get(typeName);
    }

    @Override
    public Type[] getTypes(String... typeNames) {
        List<Type> ret = new ArrayList<Type>(typeNames.length);
        for (String typeName : typeNames) {
            ret.add(types.get(typeName));
        }
        return ret.toArray(new Type[0]);
    }

    public Map<String, Type> getTypes() {
        return types;
    }
    
}
